//
// Created by sgyt on 2020/4/29.
// 非阻塞io
/***
 * 在此案例中，程序发出了9000多个write调用，但是只有500个真正输出了数据，其余都返回了错误、这种形式的循环称为轮询
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <fcntl.h>

void set_fl(int fd,int flags);
void clr_f1(int fd,int flags);
char buf[500000];


int main(int argc,char *argv[])
{
    int ntowrite,nwrite;
    char *ptr;
    int errno;

    //阻塞 读取 输入数据
    ntowrite = read(STDIN_FILENO,buf, sizeof(buf));
    fprintf(stderr,"read %d bytes\n",ntowrite);

    //设置输出为非阻塞的
    set_fl(STDOUT_FILENO,O_NONBLOCK);
    ptr = buf;
    while(ntowrite > 0)
    {
        errno = 0;
        nwrite = write(STDOUT_FILENO,ptr,ntowrite);
        fprintf(stderr,"read %d bytes\n",nwrite);

        if(nwrite > 0)
        {
            ptr += nwrite;
            ntowrite -= nwrite;
        }
    }


    clr_f1(STDOUT_FILENO,O_NONBLOCK);
    return 0;
}

void clr_f1(int fd,int flags)
{

    if(fcntl(fd,F_SETFL,flags)<0)
    {
        perror("fcntl is error\n");
    }
}


void set_fl(int fd,int flags)
{
    int val;

    if((val = fcntl(fd,F_GETFL,0)) < 0)
    {
        perror("fcntl is error\n");
    }

    val |= flags;

    if(fcntl(fd,F_SETFL,val)<0)
    {
        perror("fcntl is error\n");
    }
}
